package com.azier.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期相关的工具类
 *
 * @author 金建强(ptma@163.com)
 * @version 2015-11-27 14:23.
 */
public final class DateUtil {

    /** 毫秒 */
    public final static long                     MS                      = 1;
    /** 每秒钟的毫秒数 */
    public final static long                     SECOND_MS               = MS * 1000;
    /** 每分钟的毫秒数 */
    public final static long                     MINUTE_MS               = SECOND_MS * 60;
    /** 每小时的毫秒数 */
    public final static long                     HOUR_MS                 = MINUTE_MS * 60;
    /** 每天的毫秒数 */
    public final static long                     DAY_MS                  = HOUR_MS * 24;

    /** 标准日期格式 */
    public final static String                   DATE_PATTERN            = "yyyy-MM-dd";
    /** 标准时间格式 */
    public final static String                   TIME_PATTERN            = "HH:mm:ss";
    /** 标准日期时间格式，精确到分 */
    public final static String                   DATETIME_MINUTE_PATTERN = "yyyy-MM-dd HH:mm";
    /** 标准日期时间格式，精确到秒 */
    public final static String                   DATETIME_PATTERN        = "yyyy-MM-dd HH:mm:ss";
    /** 标准日期时间格式，精确到毫秒 */
    public final static String                   DATETIME_MS_PATTERN     = "yyyy-MM-dd HH:mm:ss.SSS";
    /** HTTP头中日期时间格式 */
    public final static String                   HTTP_DATETIME_PATTERN   = "EEE, dd MMM yyyy HH:mm:ss z";

    private static ThreadLocal<SimpleDateFormat> NORM_DATE_FORMAT        = new ThreadLocal<SimpleDateFormat>() {

                                                                             @Override
                                                                             synchronized protected SimpleDateFormat initialValue() {
                                                                                 return new SimpleDateFormat(
                                                                                                             DATE_PATTERN);
                                                                             }
                                                                         };
    /** 标准时间格式化器 */
    private static ThreadLocal<SimpleDateFormat> NORM_TIME_FORMAT        = new ThreadLocal<SimpleDateFormat>() {

                                                                             @Override
                                                                             synchronized protected SimpleDateFormat initialValue() {
                                                                                 return new SimpleDateFormat(
                                                                                                             TIME_PATTERN);
                                                                             }
                                                                         };
    /** 标准日期时间格式化器 */
    private static ThreadLocal<SimpleDateFormat> NORM_DATETIME_FORMAT    = new ThreadLocal<SimpleDateFormat>() {

                                                                             @Override
                                                                             synchronized protected SimpleDateFormat initialValue() {
                                                                                 return new SimpleDateFormat(
                                                                                                             DATETIME_PATTERN);
                                                                             }
                                                                         };
    /** HTTP日期时间格式化器 */
    private static ThreadLocal<SimpleDateFormat> HTTP_DATETIME_FORMAT    = new ThreadLocal<SimpleDateFormat>() {

                                                                             @Override
                                                                             synchronized protected SimpleDateFormat initialValue() {
                                                                                 return new SimpleDateFormat(
                                                                                                             HTTP_DATETIME_PATTERN,
                                                                                                             Locale.US);
                                                                             }
                                                                         };

    private DateUtil(){
    }

    /**
     * 当前时间，格式 yyyy-MM-dd HH:mm:ss
     *
     * @return 当前时间的标准形式字符串
     */
    public static String nowString() {
        return formatDateTime(new Date());
    }

    /**
     * 得到当前时间的时间戳
     *
     * @return 当前时间戳 Timestamp
     */
    public static Timestamp now() {
        long curTime = System.currentTimeMillis();
        return new Timestamp(curTime);
    }

    /**
     * 给定的日期是不是今日
     *
     * @param date
     * @return
     */
    public static boolean isToday(Date date) {
        Date now = now();
        return year(date)==year(now) && month(date)==month(now) && day(date)==day(now);
    }

    /**
     * 当前日期，格式 yyyy-MM-dd
     *
     * @return 当前日期的标准形式字符串
     */
    public static String today() {
        return formatDate(new Date());
    }

    /**
     * @return 当前日
     */
    public static int thisDay() {
        return day(date());
    }

    /**
     * @return 当前月份
     */
    public static int thisMonth() {
        return month(date());
    }

    /**
     * @return 今年
     */
    public static int thisYear() {
        return year(date());
    }

    /**
     * @return 当前时间
     */
    public static Date date() {
        return new Date();
    }

    /**
     * @return 上个月份
     */
    public static int lastMonthInt() {
        return month(lastMouth());
    }

    /**
     * Long类型时间转为Date
     *
     * @param date Long类型Date（Unix时间戳）
     * @return 时间对象
     */
    public static Date date(long date) {
        return new Date(date);
    }

    /**
     * 转换为Calendar对象
     *
     * @param date 日期对象
     * @return Calendar对象
     */
    public static Calendar toCalendar(Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal;
    }

    /**
     * 获取某天的开始时间(yyyy-MM-dd 00:00:00.000)
     *
     * @param date 日期
     * @return 某天的开始时间
     */
    public static Date beginTimeOfDay(Date date) {
        Calendar calendar = toCalendar(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取某天的结束时间(yyyy-MM-dd 23:59:59.999)
     *
     * @param date 日期
     * @return 某天的结束时间
     */
    public static Date endTimeOfDay(Date date) {
        Calendar calendar = toCalendar(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 获取某月的开始时间(yyyy-MM-01 00:00:00.000)
     *
     * @param date 日期
     * @return 某月的开始时间
     */
    public static Date beginTimeOfMonth(Date date) {
        Calendar calendar = toCalendar(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取某月的结束时间(yyyy-MM-31 23:59:59.999)
     *
     * @param date 日期
     * @return 某月的结束时间
     */
    public static Date endTimeOfMonth(Date date) {
        Calendar calendar = toCalendar(date);
        int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        calendar.set(Calendar.DAY_OF_MONTH, lastDay);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 获得日
     *
     * @param date 日期
     * @return 月份
     */
    public static int day(Date date) {
        return toCalendar(date).get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获得月份
     *
     * @param date 日期
     * @return 月份
     */
    public static int month(Date date) {
        return toCalendar(date).get(Calendar.MONTH) + 1;
    }

    /**
     * 获得年
     *
     * @param date 日期
     * @return 月份
     */
    public static int year(Date date) {
        return toCalendar(date).get(Calendar.YEAR);
    }

    /**
     * 获得年
     *
     * @param date 日期
     * @return 月份
     */
    public static int season(Date date) {
        return toCalendar(date).get(Calendar.MONTH) / 3 + 1;
    }

    /**
     * 获得指定日期年份和季节<br>
     * 格式：[20131]表示2013年第一季度
     *
     * @param date 日期
     * @return Season ，类似于 20132
     */
    public static String yearAndSeason(Date date) {
        return yearAndSeason(toCalendar(date));
    }

    /**
     * 获得指定日期区间内的年份和季节<br>
     *
     * @param startDate 其实日期（包含）
     * @param endDate 结束日期（包含）
     * @return Season列表 ，元素类似于 20132
     */
    public static Set<String> yearAndSeasons(final Date startDate, final Date endDate) {
        final LinkedHashSet<String> seasons = new LinkedHashSet<String>();
        if (startDate == null || endDate == null) {
            return seasons;
        }

        Date theStartDate = startDate;
        final Calendar cal = Calendar.getInstance();
        cal.setTime(theStartDate);
        while (true) {
            // 如果开始时间超出结束时间，让结束时间为开始时间，处理完后结束循环

            if (theStartDate.after(endDate)) {
                theStartDate = endDate;
            }

            seasons.add(yearAndSeason(cal));

            if (theStartDate.equals(endDate)) {
                break;
            }

            cal.add(Calendar.MONTH, 3);
            theStartDate = cal.getTime();
        }

        return seasons;
    }

    /**
     * 根据特定格式格式化日期
     *
     * @param date 被格式化的日期
     * @param format 格式
     * @return 格式化后的字符串
     */
    public static String format(Date date, String format) {
        return new SimpleDateFormat(format).format(date);
    }

    /**
     * 格式 yyyy-MM-dd HH:mm:ss
     *
     * @param date 被格式化的日期
     * @return 格式化后的日期
     */
    public static String formatDateTime(Date date) {
        return NORM_DATETIME_FORMAT.get().format(date);
    }

    /**
     * 格式 yyyy-MM-dd
     *
     * @param date 被格式化的日期
     * @return 格式化后的字符串
     */
    public static String formatDate(Date date) {
        return NORM_DATE_FORMAT.get().format(date);
    }

    /**
     * 格式化为Http的标准日期格式
     *
     * @param date 被格式化的日期
     * @return HTTP标准形式日期字符串
     */
    public static String formatHttpDate(Date date) {
        return HTTP_DATETIME_FORMAT.get().format(date);
    }

    /**
     * 构建DateTime对象
     *
     * @param dateStr Date字符串
     * @param simpleDateFormat 格式化器
     * @return DateTime对象
     */
    public static Date parse(String dateStr, SimpleDateFormat simpleDateFormat) {
        try {
            return simpleDateFormat.parse(StringUtil.trim(dateStr));
        } catch (Exception e) {
            throw new RuntimeException(StringUtil.format("Parse [{}] with format [{}] error!", dateStr,
                                                         simpleDateFormat.toPattern()), e);
        }
    }

    /**
     * 将特定格式的日期转换为Date对象
     *
     * @param dateString 特定格式的日期
     * @param format 格式，例如yyyy-MM-dd
     * @return 日期对象
     */
    public static Date parse(String dateString, String format) {
        return parse(dateString, new SimpleDateFormat(format));
    }

    /**
     * 格式yyyy-MM-dd HH:mm:ss
     *
     * @param dateString 标准形式的时间字符串
     * @return 日期对象
     */
    public static Date parseDateTime(String dateString) {
        return parse(dateString, NORM_DATETIME_FORMAT.get());
    }

    /**
     * 格式yyyy-MM-dd
     *
     * @param dateString 标准形式的日期字符串
     * @return 日期对象
     */
    public static Date parseDate(String dateString) {
        return parse(dateString, NORM_DATE_FORMAT.get());
    }

    /**
     * 格式HH:mm:ss
     *
     * @param timeString 标准形式的日期字符串
     * @return 日期对象
     */
    public static Date parseTime(String timeString) {
        return parse(timeString, NORM_TIME_FORMAT.get());
    }

    /**
     * 格式：<br>
     * 1、yyyy-MM-dd HH:mm:ss<br>
     * 2、yyyy-MM-dd<br>
     * 3、HH:mm:ss<br>
     * 4、yyyy-MM-dd HH:mm 5、yyyy-MM-dd HH:mm:ss.SSS
     *
     * @param dateStr 日期字符串
     * @return 日期
     */
    public static Date parse(String dateStr) {
        if (null == dateStr) {
            return null;
        }
        String theDateStr = dateStr.trim();
        int length = theDateStr.length();
        try {
            if (length == DATETIME_PATTERN.length()) {
                return parseDateTime(theDateStr);
            } else if (length == DATE_PATTERN.length()) {
                return parseDate(theDateStr);
            } else if (length == TIME_PATTERN.length()) {
                return parseTime(theDateStr);
            } else if (length == DATETIME_MINUTE_PATTERN.length()) {
                return parse(theDateStr, DATETIME_MINUTE_PATTERN);
            } else if (length >= DATETIME_MS_PATTERN.length() - 2) {
                return parse(theDateStr, DATETIME_MS_PATTERN);
            }
        } catch (Exception e) {
            throw new RuntimeException(StringUtil.format("Parse [{}] with format NORMAL error!", theDateStr), e);
        }

        // 没有更多匹配的时间格式
        throw new RuntimeException(StringUtil.format(" [{}] format is not fit for date pattern!", theDateStr));
    }

    /**
     * 昨天
     *
     * @return 昨天
     */
    public static Date yesterday() {
        return offsetDay(new Date(), -1);
    }

    /**
     * 上周
     *
     * @return 上周
     */
    public static Date lastWeek() {
        return offsetWeek(new Date(), -1);
    }

    /**
     * 上个月
     *
     * @return 上个月
     */
    public static Date lastMouth() {
        return offsetMonth(new Date(), -1);
    }

    /**
     * 去年
     */
    public static Date lastYear() {
        return offsetYear(new Date(), -1);
    }

    /**
     * 两个日期里取大的
     *
     * @param date1
     * @param date2
     * @return
     */
    public static Date max(Date date1, Date date2) {
        int i = date1.compareTo(date2);
        return i>=0? date1: date2;
    }

    /**
     * 两个日期里取小的
     *
     * @param date1
     * @param date2
     * @return
     */
    public static Date min(Date date1, Date date2) {
        int i = date1.compareTo(date2);
        return i>=0? date2: date1;
    }

    /**
     * 偏移秒
     *
     * @param date 日期
     * @param offsite 偏移秒数，正数向未来偏移，负数向历史偏移
     * @return 偏移后的日期
     */
    public static Date offsetSecond(Date date, int offsite) {
        return offsetDate(date, Calendar.SECOND, offsite);
    }

    /**
     * 偏移分钟
     *
     * @param date 日期
     * @param offsite 偏移分钟数，正数向未来偏移，负数向历史偏移
     * @return 偏移后的日期
     */
    public static Date offsetMinute(Date date, int offsite) {
        return offsetDate(date, Calendar.MINUTE, offsite);
    }

    /**
     * 偏移小时
     *
     * @param date 日期
     * @param offsite 偏移小时数，正数向未来偏移，负数向历史偏移
     * @return 偏移后的日期
     */
    public static Date offsetHour(Date date, int offsite) {
        return offsetDate(date, Calendar.HOUR_OF_DAY, offsite);
    }

    /**
     * 偏移天
     *
     * @param date 日期
     * @param offsite 偏移天数，正数向未来偏移，负数向历史偏移
     * @return 偏移后的日期
     */
    public static Date offsetDay(Date date, int offsite) {
        return offsetDate(date, Calendar.DAY_OF_YEAR, offsite);
    }

    /**
     * 偏移周
     *
     * @param date 日期
     * @param offsite 偏移周数，正数向未来偏移，负数向历史偏移
     * @return 偏移后的日期
     */
    public static Date offsetWeek(Date date, int offsite) {
        return offsetDate(date, Calendar.WEEK_OF_YEAR, offsite);
    }

    /**
     * 偏移年
     *
     * @param date 日期
     * @param offsite 偏移年数，正数向未来偏移，负数向历史偏移
     * @return 偏移后的日期
     */
    public static Date offsetYear(Date date, int offsite) {
        return offsetDate(date, Calendar.YEAR, offsite);
    }

    /**
     * 偏移月
     *
     * @param date 日期
     * @param offsite 偏移月数，正数向未来偏移，负数向历史偏移
     * @return 偏移后的日期
     */
    public static Date offsetMonth(Date date, int offsite) {
        return offsetDate(date, Calendar.MONTH, offsite);
    }

    /**
     * 获取指定日期偏移指定时间后的时间
     *
     * @param date 基准日期
     * @param calendarField 偏移的粒度大小（小时、天、月等）使用Calendar中的常数
     * @param offsite 偏移量，正数为向后偏移，负数为向前偏移
     * @return 偏移后的日期
     */
    public static Date offsetDate(Date date, int calendarField, int offsite) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(calendarField, offsite);
        return cal.getTime();
    }

    /**
     * 判断两个日期相差的天数<br>
     *
     * @param d1 日期1
     * @param d2 日期2
     * @return 返回两个日期之间的天数差
     */
    public static int diffDays(Date d1, Date d2) {
        BigDecimal bd1 = new BigDecimal(d1.getTime());
        BigDecimal bd2 = new BigDecimal(d2.getTime());
        BigDecimal divisor = new BigDecimal(24L * 60 * 60 * 1000);
        BigDecimal timeQuantum = bd2.subtract(bd1).divide(divisor, RoundingMode.CEILING);
        return timeQuantum.intValue();
    }

    /**
     * 判断两个日期相差的小时数<br>
     *
     * @param d1 日期1
     * @param d2 日期2
     * @return 返回两个日期之间的小时差
     */
    public static long diffHours(Date d1, Date d2) {
        BigDecimal bd1 = new BigDecimal(d1.getTime());
        BigDecimal bd2 = new BigDecimal(d2.getTime());
        BigDecimal divisor = new BigDecimal(60L * 60 * 1000);
        BigDecimal timeQuantum = bd2.subtract(bd1).divide(divisor, RoundingMode.CEILING);
        return timeQuantum.longValue();
    }

    /**
     * 判断两个日期相差的分钟数<br>
     *
     * @param d1 日期1
     * @param d2 日期2
     * @return 返回两个日期之间的分钟差
     */
    public static long diffMinutes(Date d1, Date d2) {
        BigDecimal bd1 = new BigDecimal(d1.getTime());
        BigDecimal bd2 = new BigDecimal(d2.getTime());
        BigDecimal divisor = new BigDecimal(60L * 1000);
        BigDecimal timeQuantum = bd2.subtract(bd1).divide(divisor, RoundingMode.CEILING);
        return timeQuantum.longValue();
    }

    /**
     * 判断两个日期相差的秒数<br>
     *
     * @param d1 日期1
     * @param d2 日期2
     * @return 返回两个日期之间的秒差
     */
    public static long diffSeconds(Date d1, Date d2) {
        BigDecimal bd1 = new BigDecimal(d1.getTime());
        BigDecimal bd2 = new BigDecimal(d2.getTime());
        BigDecimal divisor = new BigDecimal(1000L);
        BigDecimal timeQuantum = bd2.subtract(bd1).divide(divisor, RoundingMode.CEILING);
        return timeQuantum.longValue();
    }

    /**
     * 计时，常用于记录某段代码的执行时间，单位：纳秒
     *
     * @param preTime 之前记录的时间
     * @return 时间差，纳秒
     */
    public static long spendNt(long preTime) {
        return System.nanoTime() - preTime;
    }

    /**
     * 计时，常用于记录某段代码的执行时间，单位：毫秒
     *
     * @param preTime 之前记录的时间
     * @return 时间差，毫秒
     */
    public static long spendMs(long preTime) {
        return System.currentTimeMillis() - preTime;
    }

    /**
     * 获取1970年1月1日0时0分0秒到当前时间点所经过的秒数
     *
     * @return 32bit 整形
     */
    public static int getUTCSeconds() {
        Date date = new Date();
        return (int) Math.abs(date.getTime() / 1000);
    }

    /**
     * 转换 UTC 秒数为日期
     * @param timestamp
     * @return
     */
    public static Date convertUTC2Date(int timestamp) {
        return new Date(timestamp * 1000L);
    }

    /**
     * 格式化 UTC 秒数为日期格式
     * @param timestamp
     * @return
     */
    public static String formatUTC(int timestamp) {
        Date date = new Date(timestamp * 1000L);
        return format(date, DATETIME_PATTERN);
    }

    /**
     * 格式化 UTC 毫秒秒数为日期格式
     * @param timestamp
     * @return
     */
    public static String formatUTCms(long timestamp) {
        Date date = new Date(timestamp);
        return format(date, DATETIME_MS_PATTERN);
    }

    /**
     * 计算指定指定时间区间内的周数
     *
     * @param start 开始时间
     * @param end 结束时间
     * @return 周数
     */
    public static int weekCount(Date start, Date end) {
        final Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(start);
        final Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(end);

        final int startWeekofYear = startCalendar.get(Calendar.WEEK_OF_YEAR);
        final int endWeekofYear = endCalendar.get(Calendar.WEEK_OF_YEAR);

        int count = endWeekofYear - startWeekofYear + 1;

        if (Calendar.SUNDAY != startCalendar.get(Calendar.DAY_OF_WEEK)) {
            count--;
        }

        return count;
    }

    // ------------------------------------------------------------------------ Private method start

    /**
     * 获得指定日期年份和季节<br>
     * 格式：[20131]表示2013年第一季度
     *
     * @param cal 日期
     */
    private static String yearAndSeason(Calendar cal) {
        return new StringBuilder().append(cal.get(Calendar.YEAR)).append(cal.get(Calendar.MONTH) / 3 + 1).toString();
    }

    /**
     * 显示秒值为 **天**时**分**秒 3天10小时
     *
     * @param totalSeconds 秒数
     */
    public static String prettySeconds(int totalSeconds) {
        StringBuilder s = new StringBuilder();
        int second = totalSeconds % 60;

        if(totalSeconds==0){
            s.append("0秒");
            return s.toString();
        }

        if (totalSeconds > 0) {
            s.append("秒");
            s.append(StringUtil.reverse(String.valueOf(second)));
        }

        int totalMinutes = totalSeconds / 60;
        int minute = totalMinutes % 60;
        if (totalMinutes > 0) {
            s.append("分");
            s.append(StringUtil.reverse(String.valueOf(minute)));
        }

        int totalHours = totalMinutes / 60;
        int hour = totalHours % 24;
        if (totalHours > 0) {
            s.append(StringUtil.reverse("小时"));
            s.append(StringUtil.reverse(String.valueOf(hour)));
        }

        int totalDays = totalHours / 24;
        if (totalDays > 0) {
            s.append("天");
            s.append(StringUtil.reverse(String.valueOf(totalDays)));
        }

        return s.reverse().toString();
    }

    /**
     * 显示分钟数值为 **天**时**分 3天10小时
     *
     * @param totalMinutes 分钟数
     */
    public static String prettyMinutes(int totalMinutes) {
        StringBuilder s = new StringBuilder();
        int minute = totalMinutes % 60;
        if (totalMinutes > 0) {
            s.append("分");
            s.append(StringUtil.reverse(String.valueOf(minute)));
        }

        int totalHours = totalMinutes / 60;
        int hour = totalHours % 24;
        if (totalHours > 0) {
            s.append(StringUtil.reverse("小时"));
            s.append(StringUtil.reverse(String.valueOf(hour)));
        }

        int totalDays = totalHours / 24;
        if (totalDays > 0) {
            s.append("天");
            s.append(StringUtil.reverse(String.valueOf(totalDays)));
        }

        return s.reverse().toString();
    }

    /**
     * 获取当前日期是星期几<br>
     *
     * @param dt
     * @return 当前日期是星期几
     */
    public static int getWeekOfDate(Date dt) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0) {
            w = 0;
        }
        return w;
    }

    /**
     * 得到指定月的天数
     * */
    public static int getMonthLastDay(int year, int month)
    {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.YEAR, year);
        a.set(Calendar.MONTH, month - 1);
        a.set(Calendar.DATE, 1);//把日期设置为当月第一天
        a.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }

    /**
     * 获取本周一的开始时间(yyyy-MM-dd 00:00:00.000)
     *
     * @param date 日期
     * @return 本周一的开始时间
    * */
    public static Date getThisWeekMonday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }
}
